﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Xml.Linq;
using Microsoft.Office.Interop.Excel;

namespace MouseExtender.Localizer
{
    class Program
    {
        private const string localizationsSpreadsheetPath = @"..\..\..\SolutionItems\localizations.xls";
        private const string resourcesPath = @"..\..\..\MouseExtender\Resources\";
        private const string googleDocs_resourseKey = "0ApGs_mrKFgXDdEMzME04aDhxQm5NX1hOZE5XZGpZQUE";
        private const string spreadSheetUrl = "https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key={0}&exportFormat=xls";

        public static void Main(string[] args)
        {
            Console.WriteLine("Downloading localization spreadsheet...");
            DownloadSpreadSheet();

            Console.WriteLine("Reading localization....");
            Application app = new Application();
            Workbook wb = null;
            try
            {
                string localizationSpreadsheetLocation = Path.Combine(Directory.GetCurrentDirectory(), localizationsSpreadsheetPath);
                wb = app.Workbooks.Open(localizationSpreadsheetLocation);
                Worksheet ws = (Worksheet)wb.Worksheets.get_Item(1);

                foreach (Range column in ws.Columns)
                {
                    try
                    {
                        if (column.Column <= 2)
                            continue;

                        string language = (((Range)column.Cells[3]).get_Value() ?? String.Empty).ToString();
                        if (String.IsNullOrEmpty(language))
                        {
                            break;
                        }

                        UpdateLanguage(column, language);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Exception occured during update of column {0}.{2}{1}", column.Column, ex, Environment.NewLine);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception occured: {1}{0}", ex, Environment.NewLine);
            }
            finally
            {
                if (wb != null)
                {
                    wb.Close();
                }
                app.Quit();
            }
        }

        private static void UpdateLanguage(Range column, string language)
        {
            string resourceFileName = Directory.GetFiles(resourcesPath, "UIResources." + language + "*.resx").FirstOrDefault();

            XDocument resourceDoc = null;
            if (File.Exists(resourceFileName))
            {
                resourceDoc = XDocument.Load(resourceFileName);
            }
            else
            {
                resourceFileName = String.Format("{0}UIResources.{1}.resx", resourcesPath, language);
                File.Copy(resourcesPath + "UIResources.resx", resourceFileName);
                resourceDoc = XDocument.Load(resourceFileName);
            }
            List<XElement> dataElements = resourceDoc.Root.Elements("data").ToList();
            dataElements.Remove();

            foreach (Range cell in column.Cells)
            {
                if (cell.Row <= 3)
                    continue;

                string fieldName = (((Range)cell.EntireRow.Cells[1]).get_Value() ?? String.Empty).ToString();
                if (String.IsNullOrEmpty(fieldName))
                    break;

                XElement dataElement = new XElement("data",
                  new XAttribute("name", fieldName),
                  new XAttribute(XName.Get("{xml}space"), "preserve"),
                  new XElement("value"));
                resourceDoc.Root.Add(dataElement);

                object value = cell.get_Value();
                if (value != null)
                {
                    dataElement.Element("value").SetValue(value);
                    Console.WriteLine("Added value: {0}  {1}:    {2}", language, fieldName, value);
                }
                else
                {
                    break;
                }
            }

            resourceDoc.Save(resourceFileName);
        }

        public static void DownloadSpreadSheet()
        {
            Console.WriteLine("Authenticating request...");
            string auth = AuthenticateRequest();

            Console.WriteLine("Downloading file...");
            DownloadFile(auth);
        }

        private static void DownloadFile(string auth)
        {
            string url = String.Format(spreadSheetUrl, googleDocs_resourseKey);
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.Method = "GET";
            string authorization = String.Format("GoogleLogin auth={0}", auth);
            request.Headers.Set("Authorization", authorization);

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using (Stream webStream = response.GetResponseStream())
            {
                using (FileStream fileStream = new FileStream(localizationsSpreadsheetPath, FileMode.Create, FileAccess.Write))
                {
                    StreamHelper.CopyStream(webStream, fileStream);
                    fileStream.Flush();
                }
            }
        }

        private static string AuthenticateRequest()
        {
            string auth = null;
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://www.google.com/accounts/ClientLogin");
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            string postForm = "accountType=GOOGLE&Email=mouse.extender@gmail.com&Passwd=Dv3W88Ta&service=wise&source=ME-MouseExteder-1.0";
            byte[] buffer = Encoding.ASCII.GetBytes(postForm);
            using (Stream stream = request.GetRequestStream())
            {
                stream.Write(buffer, 0, buffer.Length);
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using (Stream stream = response.GetResponseStream())
            {
                using (StreamReader sr = new StreamReader(stream))
                {
                    while (!sr.EndOfStream)
                    {
                        string str = sr.ReadLine();
                        if (str.StartsWith("Auth="))
                        {
                            auth = str.Substring(5);
                            break;
                        }
                    }
                }
            }

            return auth;
        }
    }
}
